﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Npgsql;

namespace PGMapper
{
    class PostgresTransaction
    {
        public NpgsqlConnection Connection { get; set; }
        NpgsqlTransaction transaction;
        int depth; // i wonder if Npgsql/Postgres does this already?
        bool rollback;
        bool done;

        public PostgresTransaction(NpgsqlConnection connection)
        {
            Connection = connection;
        }

        public void Begin()
        {
            ThrowIfDone();

            if (depth == 0)
            {
                Connection.Open();
                transaction = Connection.BeginTransaction();
            }

            depth++;
        }

        public bool Commit()
        {
            ThrowIfDone();

            depth--;

            if (depth == 0)
            {
                PerformAction();
                return true;
            }
            return false;
        }

        public bool Rollback()
        {
            ThrowIfDone();

            rollback = true;
            depth--;

            if (depth == 0)
            {
                PerformAction();
                return true;
            }
            return false;
        }

        void PerformAction()
        {
            if (rollback)
                transaction.Rollback();
            else
                transaction.Commit();

            Connection.Close();
            done = true;
        }

        void ThrowIfDone()
        {
            if (done) throw new InvalidOperationException("Transaction was already committed or rolled back!");
        }

    }
}
